import logging
import time
import sys
from configs import app_config
from contexts.wrapper import RecyclableContextVar
from agent_app import AgentApp


# ----------------------------
# Application Factory Function
# ----------------------------
def create_flask_app_with_configs() -> AgentApp:
    """
    create a raw flask app
    with configs loaded from .env file
    """
    agent_app = AgentApp(__name__)
    agent_app.config.from_mapping(app_config.model_dump())

    # add before request hook
    @agent_app.before_request
    def before_request():
        # add an unique identifier to each request
        RecyclableContextVar.increment_thread_recycles()

    return agent_app


def create_app() -> AgentApp:
    start_time = time.perf_counter()
    app = create_flask_app_with_configs()
    initialize_extensions(app)
    end_time = time.perf_counter()
    if app_config.DEBUG:
        logging.info(f"Finished create_app ({round((end_time - start_time) * 1000, 2)} ms)")
    return app

##lobyliang
def is_celery_worker() -> bool:
    is_celery = False
    try:
        is_celery = sys.argv.index("worker")>0 and sys.argv.index("app.celery")>0
    except:
        pass
    return is_celery

def is_celery_beat() -> bool:
    is_beat = False
    try:
        is_beat = sys.argv.index("beat")>0 and sys.argv.index("app.celery")>0
    except:
        pass
    return is_beat

def is_db_command()->bool:
    if len(sys.argv) > 1 and sys.argv[0].endswith("flask") and sys.argv[1] == "db":
        return True
    return False
####

def initialize_extensions(app: AgentApp):
    is_celery = is_celery_worker()
    print(f"is_celery: {is_celery}")
    is_beat = is_celery_beat()
    print(f"is_beat: {is_beat}")
    is_db_migrate = is_db_command()
    print(f"is_db_migrate: {is_db_migrate}")

    from extensions import (
        ext_app_metrics,
        ext_blueprints,
        ext_celery,
        ext_commands,
        ext_compress,
        ext_database,
        ext_import_modules,
        ext_logging,
        ext_login,
        ext_mail,
        ext_migrate,
        ext_otel,
        ext_otel_patch,
        ext_proxy_fix,
        ext_redis,
        ext_sentry,
        ext_set_secretkey,
        ext_storage,
        ext_timezone,
        ext_warnings,
        ext_bable,
    )

    extensions = [
        ext_timezone,
        ext_logging,
        ext_warnings,
        ext_import_modules,
        ext_set_secretkey,
        ext_compress,
        ext_database,
        ext_app_metrics,
        ext_migrate,
        ext_redis,
        ext_storage,
        ext_celery,
        ext_login,
        ext_mail,
        ext_sentry,
        ext_proxy_fix,
        ext_blueprints,
        ext_commands,
        ext_otel_patch,  # Apply patch before initializing OpenTelemetry
        ext_otel,
        ext_bable,
    ]
    # if not is_celery and not is_beat and not is_db_migrate:
    #     print("Initialize robot")
    #     import os

    #     # 获取当前脚本的绝对路径
    #     current_script_path = os.path.abspath(__file__)
    #     # 获取当前脚本所在的目录
    #     current_directory = os.path.dirname(current_script_path)
    #     os.environ['LD_LIBRARY_PATH'] = current_directory+'/'
    #     from extensions import (
            
    #     )
    #     extensions.extend([
    #     ])
    for ext in extensions:
        short_name = ext.__name__.split(".")[-1]
        is_enabled = ext.is_enabled() if hasattr(ext, "is_enabled") else True
        if not is_enabled:
            if app_config.DEBUG:
                logging.info(f"Skipped {short_name}")
            continue

        start_time = time.perf_counter()
        ext.init_app(app)
        end_time = time.perf_counter()
        if app_config.DEBUG:
            logging.info(f"Loaded {short_name} ({round((end_time - start_time) * 1000, 2)} ms)")


def create_migrations_app():
    app = create_flask_app_with_configs()
    from extensions import ext_database, ext_migrate

    # Initialize only required extensions
    ext_database.init_app(app)
    ext_migrate.init_app(app)

    return app
